package fcc.Seng462project.client;



import java.util.ArrayList;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormHandler;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormSubmitEvent;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.user.client.ui.Anchor;

import fcc.Seng462project.client.entities.FileInfo;



/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Seng462Project implements EntryPoint {
	private String userID;
	private LoginInfo loginInfo=null;
	private VerticalPanel loginPanel = new VerticalPanel();
	private Label loginLabel= new Label("Please Sign in to your Google Account!");
	private Anchor signInLink = new Anchor("Sign In");
	private Anchor signOutLink=new Anchor("Sign Out");
	
	//create a dialog for login interface
	private final LoginDialog mLoginDialog=new LoginDialog();
   //create a dialog for register interface
	private final EditDialog RegisterDialog=new EditDialog();
   //create a dialog for findpasswrod inteface
	private final EditDialog FindPasswordDialog = new EditDialog();
	//create layout to display the files
	private final ContentInterface conInterface=new ContentInterface();
	private final LoginDialog logInterface=new LoginDialog();
	//create a dialog for share file interface
	private final shareDialog sharedialog=new shareDialog();
	
	private final UserLogInAsync userlogin=GWT.create(UserLogIn.class);
	BlobServiceAsync blobService = GWT.create(BlobService.class);

	
	HTML share;//=new HTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
	
	HTML remove;//=new HTML("<img src="+basePage+"image/file_delete.png width=25 height=25>");
	
	private ArrayList<FileInfo> results;
		
	public void onModuleLoad() {
		RootPanel rootPanel = RootPanel.get();
		//LoginDialog logInterface=new LoginDialog();
		rootPanel.add(logInterface);
		
		RegisterDialog.nameLabel.setText("Email");
		RegisterDialog.phonenumberLabel.setText("Password");
		
		/*
		LoginServiceAsync loginService= GWT.create(LoginService.class);
		
	    loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {
	        public void onFailure(Throwable error) {
	        }

	        public void onSuccess(LoginInfo result) {
	          loginInfo = result;
	          if(loginInfo.isLoggedIn()) {
	            //Window.alert("hello");
	        	  enterMainPage();
	          } else {
	            loadLogin();
	          }
	        }
	      });
	    
	    */
	  //if users click login button, go to Login()
		logInterface.LoginButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				Login();
			}
		});
    //if users click regist, register dialog popup
		logInterface.RegisterButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				showRegisterDialog();
			}
		});
		//click confirm button on the register dialog, go to reguser()
		RegisterDialog.confirmButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				regUser();
				RegisterDialog.Cancel();
			}
		});
		
	      	
	}
	

	
	private void showRegisterDialog(){
		
		RegisterDialog.center();
		RegisterDialog.show();
	}
   
   /*catch user's input
   *make RPC Call to the service
   *and pass data=username+","+password
   *
   */
	private void regUser(){
		
		final String UserEmail=RegisterDialog.nameBox.getText();
		String Password=RegisterDialog.phonenumberBox.getText();
		if(!isEmailAddressFormat(UserEmail)){
			return;
		}
		String data=UserEmail+","+Password;
	 
		Window.alert(data);
		userlogin.registerUser(data, new AsyncCallback<Void>(){
			public void onFailure(Throwable error){
				Window.alert("can not connect to the servcer");
			}
			@Override
			public void onSuccess(Void result) {
				
				Window.alert("Register Succeed");
				
			}
			
		});

	}
  /*catch user's input 
  *make a PRC call to check identify if users are able to login
  */
	private void Login(){
		String UserEmail=logInterface.PhoneNumber.getText();
		String Password=logInterface.Password.getText();
		if(!isEmailAddressFormat(UserEmail)){
			Window.alert("Please enter valid email address");
			return;
		}
		String data=UserEmail+","+Password;
		
		userlogin.loginUser(data, new AsyncCallback<String>(){
			public void onFailure(Throwable error){
				Window.alert(error.toString());
				
			}
			public void onSuccess(String ret){
				if(ret.equals("Error")){
					Window.alert("Enter Correct Email and Password");
				}else{
					userID=ret;
					enterMainPage();
				}
				
			}
		});
	}

	  /*the  main layout to list our file*/
	private void enterMainPage(){
	
		conInterface.idLabel.setText(userID);
		RootPanel.get().clear();
		RootPanel.get().add(conInterface);
		//DialogBox uploadDial=createDialogBox();
		getFileInfo(userID);
		
		//final DialogBox dialogBox;
		//dialogBox = createDialogBox();
		//dialogBox.setText("Upload your file");
		
		//rootpanel and fuck google!
		//RootPanel.get().add(dialogBox);
      //to sign out
		conInterface.SignOut.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				RootPanel.get().clear();
				logInterface.PhoneNumber.setText("");
				logInterface.Password.setText("");
				RootPanel.get().add(logInterface);
			}
		});
		//to upload a file
		conInterface.addButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				//uploadFile();
				createDialogBox();
			}
		});
		

	}
	//upload popup UI
	public void uploadFile() {
		DialogBox dialogBox= new DialogBox();
		//dialogBox = createDialogBox();
		dialogBox.setText("Upload your file");
		RootPanel.get().add(dialogBox);
	}
	//check if user has enter correct format of emailaddress
	private boolean isEmailAddressFormat(String email){
		boolean ret=false;
		int i=email.length();
		if(i==0){
			return ret;
		}
		int temp=email.indexOf('@');
		int tempd=email.indexOf('.');
		if(temp<=1){
			return ret;
		}
		if(tempd<=1){
			return ret;
		}
		if(tempd-temp<=0){
			return ret;
		}
		if(i==tempd+1){
			return ret;
		}
		return true;
	}
	
	//dialogbox layout and interface. 
	//file path goes here
	//@SuppressWarnings("deprecation")
	public void createDialogBox(){
		final DialogBox dialBox = new DialogBox();
		RootPanel.get().add(dialBox);
		dialBox.setText("Upload a file");
		//dialogBox.setAnimationEnabled(true);
		VerticalPanel dialogContents=new VerticalPanel();
		HorizontalPanel hp = new HorizontalPanel();
		FileUpload upload = new FileUpload();
		final FormPanel uploadForm = new FormPanel();
		//HTTP form parameters
		uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART);
	    uploadForm.setMethod(FormPanel.METHOD_POST);
		dialBox.setWidget(dialogContents);
		
	    hp.add(upload);
	    upload.setName("upload");
	    Button submitButton=new Button("Submit");
		Button cancelButton = new Button("Cancel", new ClickHandler(){
			public void onClick(ClickEvent event){
				dialBox.hide();
			}
		});
		hp.add(submitButton);
		hp.add(cancelButton);
		uploadForm.setWidget(hp);

		
		dialogContents.setSpacing(2);
		dialogContents.add(uploadForm);
		dialogContents.setCellHorizontalAlignment(hp, HasHorizontalAlignment.ALIGN_CENTER);

		
		Hidden fileOwner=new Hidden();
		fileOwner.setName("fileOwner");
		hp.add(fileOwner);
		//Temp values for testing
		fileOwner.setValue(userID);
		submitButton.addClickHandler(new ClickHandler() {
		      @Override
		      public void onClick(ClickEvent event) {

		        blobService.getBlobStoreUploadUrl(new AsyncCallback<String>() {

		              @Override
		              public void onSuccess(String result) {
		                // Set the form action to the newly created
		                // blobstore upload URL
		                uploadForm.setAction(result);//.toString());
		                //System.out.println("where upload form is going!"+result);//.toString());

		                // Submit the form to complete the upload
		                uploadForm.submit();
		                //System.out.println("Form action: "+uploadForm.getAction());
		                uploadForm.reset();
		                dialBox.hide();
		               //RootPanel.get().clear();
		               //RootPanel.get().add(conInterface);
		              }

		              @Override
		              public void onFailure(Throwable caught) {
		                caught.printStackTrace();
		                System.out.println("Upload fail!");
		              }
		            });

		      }
		    });
		
		uploadForm.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
          @Override
          public void onSubmitComplete(SubmitCompleteEvent event) {
            
         
        	getFileInfo(userID);
        	RootPanel.get().clear();
        	
        	RootPanel.get().add(conInterface); 
          
            System.out.println(event.getResults());

          }

        });
		

  
	}
	
	public void getFileInfo( final String username) {
		final String basePage = GWT.getHostPageBaseURL();
		
		blobService.getFileInfo(username, new AsyncCallback<ArrayList<FileInfo>>() {
			@Override
			public void onSuccess(final ArrayList<FileInfo> result) {
				int row = 1;
				//results=result;
				for (FileInfo file : result) {
					
					String fileLink = basePage.substring(0, basePage.length() -1);
					fileLink = fileLink+file.getFileUrl();
					Anchor link = new Anchor(file.getName(), fileLink, "_blank");
					//Hyperlink shareIcon = new Hyperlink();
					//shareIcon.setHTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					share=new HTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					remove=new HTML("<img src="+basePage+"image/file_delete.png width=25 height=25>");
					//HTML share=new HTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					
					//HTML remove=new HTML("<img src="+basePage+"image/file_delete.png width=25 height=25>");
					conInterface.listTable.setWidget(row, 0, link);
					//conInterface.listTable.setText(row, 0, file.getName());
					conInterface.listTable.setText(row, 1, file.getOwner());
					conInterface.listTable.setText(row, 2, file.getFileType());
					conInterface.listTable.setText(row, 3, (file.getSize()).toString());
					conInterface.listTable.setWidget(row, 4, share);
					conInterface.listTable.setWidget(row, 5, remove);
			   
					row++;
					
					//here, when you click share icon, you will find sharefile function
					//sharefile function will recieve what row you have click, which determine which
					//file you want to share., Also, it will pop up widown,ask 
					//you to type who you want to share with
					share.addClickHandler(new ClickHandler(){
						@Override
						public void onClick(ClickEvent event){
							 
				             int rowIndex = conInterface.listTable.getCellForEvent(event).getRowIndex();
				             System.out.println("I have click "+Integer.toString(rowIndex) );
				             sharefile(rowIndex,result);
				             
							
						}
					});
					//when you click remove, it will remove the row. I AM NOT SURE if they have gap
					//between two files.let say I delete file number 2, however, whether
					//file number 3 will turn to number 2 on the flextable list or not
					//WARNING: YOU NEED TO UPDATE YOU ROW NUMBER
					
					remove.addClickHandler(new ClickHandler(){
						@Override
						public void onClick(ClickEvent event){
							 
				             int rowIndex = conInterface.listTable.getCellForEvent(event).getRowIndex();
				             System.out.println("I am deleting: "+result.get(rowIndex-1).getName());
				             conInterface.listTable.removeRow(rowIndex);
				         
				             blobService.deleteBlob(result.get(rowIndex-1).getBlobkey(),new AsyncCallback<Void>() {
				            	 @Override
				     			 public void onSuccess(Void result2) {
				            		 //updateTable(username);
				            		 getFileInfo(username);
				            		 
						             System.out.println("I win!" );
						             return;
				            	 }
				            	 @Override
				            	 public void onFailure(Throwable caught) {
				            		 System.out.println("I have failed: "+caught);
				            	 }
				             });
				             System.out.println("I have delete "+Integer.toString(rowIndex) );
				             System.out.println("I have click "+Integer.toString(rowIndex) );
				             //FlexTable temp= conInterface.listTable;
				             
				             //conInterface.listTable=updateTable(rowIndex,result);
				             //
				            
				         
				             System.out.println("total row # "+ conInterface.listTable.getRowCount());
				             
							
						}
					});
					
				}
				
				
		        
				
			}
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("getFileInfo failure!!! "+caught);
			}
		});
	}

	public void sharefile(final int rowIndex,final ArrayList<FileInfo> result){
		RootPanel.get().add(sharedialog);
		System.out.println("I have recieve "+Integer.toString(rowIndex) );
		//String row=Integer.toString(rowIndex);
		sharedialog.confirmButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				String userEmail=sharedialog.nameBox.getText();
				sharedialog.nameBox.setText("");
				blobService.shareFile(userEmail, result.get(rowIndex-1).getBlobkey(),new AsyncCallback<Void>() {
	            	 @Override
	     			 public void onSuccess(Void result2) {
			             System.out.println("I win!" );
	            	 }
	            	 @Override
	            	 public void onFailure(Throwable caught) {
	            		 System.out.println("I have failed: "+caught);
	            	 }
	             });
				
				RootPanel.get().clear();
				RootPanel.get().add(conInterface);
			}
		});
		
		sharedialog.cancelButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				sharedialog.nameBox.setText("");
				RootPanel.get().clear();
				RootPanel.get().add(conInterface);
			}
		});
	}
	/*the flextable to list the files information that we have upload
     *info: file link, owner, type,size share to,remove button
   */
	public void updateTable(String username){
		final String basePage = GWT.getHostPageBaseURL();
		blobService.getFileInfo(username, new AsyncCallback<ArrayList<FileInfo>>() {
			public void onSuccess(final ArrayList<FileInfo> result) {
				int row = 1;
				//results=result;
				for (FileInfo file : result) {
					
					String fileLink = basePage.substring(0, basePage.length() -1);
					fileLink = fileLink+file.getFileUrl();
					Anchor link = new Anchor(file.getName(), fileLink, "_blank");
					//Hyperlink shareIcon = new Hyperlink();
					//shareIcon.setHTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					share=new HTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					remove=new HTML("<img src="+basePage+"image/file_delete.png width=25 height=25>");
					//HTML share=new HTML("<img src="+basePage+"image/file_share.gif width=25 height=25>");
					
					//HTML remove=new HTML("<img src="+basePage+"image/file_delete.png width=25 height=25>");
					conInterface.listTable.setWidget(row, 0, link);
					//conInterface.listTable.setText(row, 0, file.getName());
					conInterface.listTable.setText(row, 1, file.getOwner());
					conInterface.listTable.setText(row, 2, file.getFileType());
					conInterface.listTable.setText(row, 3, (file.getSize()).toString());
					conInterface.listTable.setWidget(row, 4, share);
					conInterface.listTable.setWidget(row, 5, remove);
			   
					row++;
				}
			}
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("getFileInfo failure!!! "+caught);
			}
		});
	}
	
	
	
}
